package com.anlogic.sdk.bootimage.internal.ui.common;

import com.anlogic.sdk.bootimage.internal.ui.composite.AbsBootgenComposite;
import com.anlogic.sdk.utils.StringUtils;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;

public class BootgenRadioField<V> implements IExtBootgenField<Composite, V> {
	private AbsBootgenComposite bootgenComposite;

	private IModifyListener<V> modifyListener;

	private Composite radioComposite;

	private Map<V, Button> optionButtonMap = new HashMap<>();

	private Label label;

	public BootgenRadioField(AbsBootgenComposite bootgenComposite) {
		this.bootgenComposite = bootgenComposite;
	}

	@SuppressWarnings("unchecked")
	public void createField(Composite container, String labelText, Object... options) {
		boolean labelExists = StringUtils.isNotEmpty(labelText);
		this.radioComposite = new Composite(container, 0);
		int noOfColumns = options.length;
		if (labelExists)
			noOfColumns++;
		GridLayoutFactory.fillDefaults().numColumns(noOfColumns).applyTo(this.radioComposite);
		if (labelExists) {
			this.label = new Label(this.radioComposite, 0);
			this.label.setText(labelText);
			GridDataFactory.swtDefaults().applyTo((Control) this.label);
		}
		BootgenComboLabelProvider labelProvider = new BootgenComboLabelProvider();
		for (Object option : options) {
			String btnText = labelProvider.getText(option);
			Button button = new Button(this.radioComposite, 16);
			button.setText(btnText);
			GridDataFactory.swtDefaults().applyTo((Control) button);
			this.optionButtonMap.put((V) option, button);
			addSelectionListener(button);
		}
	}

	public Label getLabel() {
		return this.label;
	}

	private void addSelectionListener(final Button button) {
		button.addSelectionListener((SelectionListener) new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (button.getSelection()) {
					V selection = BootgenRadioField.this.getSelection();
					if (!BootgenRadioField.this.bootgenComposite.isSkipNotifactions()
							&& BootgenRadioField.this.modifyListener != null)
						BootgenRadioField.this.modifyListener.valueChanged(selection);
				}
			}
		});
	}

	public V getSelection() {
		for (Map.Entry<V, Button> entry : this.optionButtonMap.entrySet()) {
			if (((Button) entry.getValue()).getSelection())
				return entry.getKey();
		}
		return null;
	}

	public void setModifyListener(IModifyListener<V> modifyListener) {
		this.modifyListener = modifyListener;
	}

	public void setSelection(V selection) {
		for (Map.Entry<V, Button> entry : this.optionButtonMap.entrySet()) {
			if (selection.equals(entry.getKey())) {
				((Button) entry.getValue()).setSelection(true);
				continue;
			}
			((Button) entry.getValue()).setSelection(false);
		}
	}

	public void setEnabled(boolean enabled) {
		getControl().setEnabled(enabled);
		if (this.label != null)
			this.label.setEnabled(enabled);
		for (Map.Entry<V, Button> entry : this.optionButtonMap.entrySet())
			((Button) entry.getValue()).setEnabled(enabled);
	}

	public void setDefaultGridData(int hSpan) {
		GridDataFactory.fillDefaults().grab(true, false).span(hSpan, 1).applyTo((Control) getControl());
	}

	public Composite getControl() {
		return this.radioComposite;
	}

	public Button getControlForOption(V option) {
		return this.optionButtonMap.get(option);
	}
}
